﻿namespace TextTools_UnitTests
{
    using System;
    using MagnusGrindalBakken.TextTools;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    [TestClass]
    public class NearestUppercaseTest
    {
        [TestMethod]
        public void DeleteLeftToNearestUppercaseEmptyLineTest()
        {
            BaseTest(string.Empty, 0, 1, true);
        }

        [TestMethod]
        public void DeleteLeftToNearestUppercaseSingleLowercaseLetterTest()
        {
            BaseTest("a", 1, 2, true);
        }

        [TestMethod]
        public void DeleteLeftToNearestUppercaseDoubleLowercaseLetterTest()
        {
            BaseTest("aa", 2, 3, true);
        }

        [TestMethod]
        public void DeleteLeftToNearestUppercaseSingleUppercaseLetterTest()
        {
            BaseTest("A", 1, 2, true);
        }

        [TestMethod]
        public void DeleteLeftToNearestUppercaseDoubleUppercaseLetterTest()
        {
            BaseTest("AA", 1, 3, true);
        }

        [TestMethod]
        public void DeleteLeftToNearestUppercaseSingleWhitespaceTest()
        {
            BaseTest(" ", 1, 2, true);
        }

        [TestMethod]
        public void DeleteLeftToNearestUppercaseDoubleWhitespaceTest()
        {
            BaseTest("  ", 1, 3, true);
        }

        [TestMethod]
        public void DeleteLeftToNearestUppercaseWordStyleTest()
        {
            BaseTest("AbAb", 2, 5, true);
        }

        [TestMethod]
        public void DeleteLeftToNearestUppercaseMidWordSingleLowercaseTest()
        {
            BaseTest("bAb", 1, 2, true);
        }

        [TestMethod]
        public void DeleteLeftToNearestUppercaseMidWordDoubleLowercaseTest()
        {
            BaseTest("bbAb", 2, 3, true);
        }

        [TestMethod]
        public void DeleteLeftToNearestUppercaseMidWordSingleUppercaseTest()
        {
            BaseTest("BAb", 1, 2, true);
        }

        [TestMethod]
        public void DeleteLeftToNearestUppercaseMidWordDoubleUppercaseTest()
        {
            BaseTest("BBAb", 1, 3, true);
        }

        [TestMethod]
        public void DeleteLeftToNearestUppercaseNonAlphanumericTest()
        {
            BaseTest("-!\"@#£¤$%&/{([)]=}?+`\\´¨^~'*-_.:,;<>", 36, 37, true);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void DeleteLeftToNearestUppercaseThrowsIfStartColumnIsLessThanOneTest()
        {
            Library.DeleteLeftToNearestUppercase("", 0);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void DeleteLeftToNearestUppercaseThrowsIfStartColumnIsTooHighTest()
        {
            Library.DeleteLeftToNearestUppercase("a", 3);
        }

        [TestMethod]
        public void DeleteRightToNearestUppercaseEmptyLineTest()
        {
            BaseTest(string.Empty, 0, 1, false);
        }

        [TestMethod]
        public void DeleteRightToNearestUppercaseSingleLowercaseLetterTest()
        {
            BaseTest("a", 1, 1, false);
        }

        [TestMethod]
        public void DeleteRightToNearestUppercaseDoubleLowercaseLetterTest()
        {
            BaseTest("aa", 2, 1, false);
        }

        [TestMethod]
        public void DeleteRightToNearestUppercaseSingleUppercaseLetterTest()
        {
            BaseTest("A", 1, 1, false);
        }

        [TestMethod]
        public void DeleteRightToNearestUppercaseDoubleUppercaseLetterTest()
        {
            BaseTest("AA", 1, 1, false);
        }

        [TestMethod]
        public void DeleteRightToNearestUppercaseSingleWhitespaceTest()
        {
            BaseTest(" ", 1, 1, false);
        }

        [TestMethod]
        public void DeleteRightToNearestUppercaseDoubleWhitespaceTest()
        {
            BaseTest("  ", 1, 1, false);
        }

        [TestMethod]
        public void DeleteRightToNearestUppercaseWordStyleTest()
        {
            BaseTest("AbAb", 2, 1, false);
        }

        [TestMethod]
        public void DeleteRightToNearestUppercaseMidWordSingleLowercaseTest()
        {
            BaseTest("bAb", 1, 1, false);
        }

        [TestMethod]
        public void DeleteRightToNearestUppercaseMidWordDoubleLowercaseTest()
        {
            BaseTest("bbAb", 2, 1, false);
        }

        [TestMethod]
        public void DeleteRightToNearestUppercaseMidWordSingleUppercaseTest()
        {
            BaseTest("BAb", 1, 1, false);
        }

        [TestMethod]
        public void DeleteRightToNearestUppercaseMidWordDoubleUppercaseTest()
        {
            BaseTest("BBAb", 1, 1, false);
        }

        [TestMethod]
        public void DeleteRightToNearestUppercaseNonAlphanumericTest()
        {
            BaseTest("-!\"@#£¤$%&/{([)]=}?+`\\´¨^~'*-_.:,;<>", 36, 1, false);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void DeleteRightToNearestUppercaseThrowsIfStartColumnIsLessThanOneTest()
        {
            Library.DeleteRightToNearestUppercase("", 0);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void DeleteRightToNearestUppercaseThrowsIfStartColumnIsTooHighTest()
        {
            Library.DeleteRightToNearestUppercase("a", 3);
        }

        public void BaseTest(string line, int expected, int startColumn, bool left)
        {
            // Act.
            int actual;
            if (left)
                actual = Library.DeleteLeftToNearestUppercase(line, startColumn);
            else
                actual = Library.DeleteRightToNearestUppercase(line, startColumn);

            // Assert.
            Assert.AreEqual(expected, actual);
        }
    }
}
